package com.yb.loadbalancer;

import com.alibaba.cloud.nacos.NacosServiceInstance;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.cloud.client.ServiceInstance;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Random;

/**
 * Copyright (C), 2022-2023, 姚兵
 * Author: 32210
 * Date: 2023/5/26 12:21
 * FileName: MyDemo
 * Description:
 */
public class MyDemo {


    public static void main(String[] args) {
        List<XczxServiceInstance> test = test();
    }


    static List<XczxServiceInstance> list=new ArrayList<>();
    static{

        XczxServiceInstance instance1 = new XczxServiceInstance("aa","11",5);
        XczxServiceInstance instance2 = new XczxServiceInstance("aa","22",3);

        XczxServiceInstance instance3 = new XczxServiceInstance("aa","33",1);

        XczxServiceInstance instance4 = new XczxServiceInstance("aa","44",4);


        list.add(instance1);
        list.add(instance2);
        list.add(instance3);
        list.add(instance4);
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class XczxServiceInstance{
        private String host;
        private String port;
        private int weight;
        private int curWeight=0;

        public XczxServiceInstance(String host,String port,int weight){
            this.host=host;
            this.port=port;
            this.weight=weight;
        }
    }

    public static List<XczxServiceInstance> test(){
        ArrayList<XczxServiceInstance> result = new ArrayList<>();
        for (int i = 0; i < 26; i++) {
            result.add(smoothChooseWeightRoundRobin());
        }
        return result;
    }
    public static XczxServiceInstance chooseRandom(){
        Random random = new Random();
        int index = random.nextInt(list.size());
        return list.get(index);
    }

    public static int curSelectIndex=0;
    public static XczxServiceInstance chooseRoundRobin(){
        curSelectIndex%=list.size();
        return list.get(curSelectIndex++);

    }


    public static int totalWeight(){
        return list.stream().map(XczxServiceInstance::getWeight).reduce(0,Integer::sum);
    }
    public static XczxServiceInstance chooseWeightRandom(){
        //总权重
        int totalWeight = totalWeight();
        
        Random random = new Random();
        int randomWeight = random.nextInt(totalWeight);

        for (XczxServiceInstance instance : list) {
            if(randomWeight<instance.getWeight()){
                return instance;
            }
            randomWeight-=instance.getWeight();
        }
        return null;
    }


    public static XczxServiceInstance chooseWeightRoundRobin(){
        int totalWeight = totalWeight();
        int tempCurSelectIndex=curSelectIndex;
        for (XczxServiceInstance xczxServiceInstance : list) {
            if(tempCurSelectIndex<xczxServiceInstance.getWeight()){
                curSelectIndex++;
                curSelectIndex%=totalWeight;
                return xczxServiceInstance;
            }
            tempCurSelectIndex-=xczxServiceInstance.getWeight();
        }
        return null;
    }


    public static XczxServiceInstance smoothChooseWeightRoundRobin(){
        int totalWeight = totalWeight();
        list.stream().forEach(item->{item.curWeight+=item.weight;});
        //找出curWeight最大的
        Optional<XczxServiceInstance> reduce = list.stream().reduce((x, y) -> x.curWeight >= y.curWeight ? x : y);
        XczxServiceInstance instance = reduce.get();
        //修改curWeight
        instance.curWeight-=totalWeight;
        return instance;
    }

}
